Skip to content

feat: init SeedlessOnboardingController via @metamask/wallet - #33413

Closed
grvgoel81 wants to merge 8 commits into
mainfrom
feat/TO-921-wallet-init-seedless
Closed

feat: init SeedlessOnboardingController via @metamask/wallet#33413
grvgoel81 wants to merge 8 commits into
mainfrom
feat/TO-921-wallet-init-seedless

Conversation

@grvgoel81

@grvgoel81 grvgoel81 commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Description

Migrates SeedlessOnboardingController construction from Mobile’s local Engine init into @metamask/wallet, matching the shared wallet init pattern (same as TransactionController / Keyring).
Why: Core #9533 wires SeedlessOnboardingController into default wallet initialization. Mobile must stop constructing a duplicate controller and instead supply client-specific instanceOptions.
What changed:

  • Added getSeedlessOnboardingControllerInstanceOptions() under wallet-init/instance-options/ (mobile Encryptor cipherdata adapter, JWT handlers via AuthTokenHandler, web3AuthNetwork, passwordOutdatedCacheTTL)
  • Wired options into initializeWallet; Engine reads the controller via wallet.getInstance('SeedlessOnboardingController')
  • Removed Mobile’s local seedless controller init + messenger factory; kept error helpers under controllers/seedless-onboarding-controller
  • Updated E2E Metro mocking to replace @metamask/seedless-onboarding-controller (wallet owns construction now)

Changelog

CHANGELOG entry: null

Related issues

Refs: https://consensyssoftware.atlassian.net/browse/TO-921

Manual testing steps

Feature: Seedless onboarding via wallet-init 

  Scenario: New user completes Google social login
    Given the app is a fresh install on a main/dev build (HAS_TEST_OVERRIDES=false)
    And SeedlessOnboardingController is available from wallet getInstance
    When the user completes Google social login and creates a password
    Then onboarding completes and the wallet unlocks successfully

  Scenario: Existing user rehydrates with social login
    Given an existing social-login wallet for the same account
    When the user signs in with Google or Telegram and unlocks
    Then vault rehydration succeeds and accounts are available

  Scenario: Lock and unlock after JWT refresh
    Given a social-login wallet that has been unlocked
    And enough time passes for background JWT refresh to rewrite the vault
    When the user locks and unlocks the wallet
    Then unlock succeeds (encryptor adapter still decrypts data/cipher vaults)

Screenshots/Recordings

Before

After

Screen.Recording.2026-07-23.at.1.01.38.PM.mov
Screen.Recording.2026-07-23.at.1.03.55.PM.mov

Pre-merge author checklist

Performance checks (if applicable)

  • I've tested on Android
    • Ideally on a mid-range device; emulator is acceptable
  • I've tested with a power user scenario
    • Use these power-user SRPs to import wallets with many accounts and tokens
  • I've instrumented key operations with Sentry traces for production performance metrics

For performance guidelines and tooling, see the Performance Guide.

Pre-merge reviewer checklist

  • I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed).
  • I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots.

Note

High Risk
Touches seedless vault encryption, OAuth/JWT refresh, and wallet initialization—security-sensitive onboarding paths—with a breaking preview @metamask/wallet dependency.

Overview
Seedless onboarding is no longer constructed through the Engine’s seedlessOnboardingControllerInit messenger path. @metamask/wallet now owns SeedlessOnboardingController lifecycle; mobile supplies client options via getSeedlessOnboardingControllerInstanceOptions() in wallet-init/instance-options/seedless-onboarding-controller.ts.

That builder carries the same mobile-specific wiring that lived in the deleted init: encryptor adapter (cipherdata, vault normalization), Web3Auth network, JWT handlers from AuthTokenHandler, and env validation. Init tests moved to the new module; the old controller init and seedless messenger factory were removed from Engine/messengers registration. Engine resolves the controller with this.#wallet.getInstance('SeedlessOnboardingController') instead of messengerClientsByName.

Dependencies: preview builds of @metamask/wallet and @metamask/seedless-onboarding-controller are pinned in package.json / yarn.lock. E2E Metro mocks @metamask/seedless-onboarding-controller (via tests/module-mocking/seedless/package.ts) instead of the former init module path. CODEOWNERS updated for the new wallet-init files.

Reviewed by Cursor Bugbot for commit d4c8ff5. Configure here.

@github-actions

Copy link
Copy Markdown
Contributor

CLA Signature Action: All authors have signed the CLA. You may need to manually re-run the blocking PR check if it doesn't pass in a few minutes.

@metamask-ci metamask-ci Bot added the team-onboarding Onboarding team label Jul 16, 2026
@metamask-ci

metamask-ci Bot commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

PR template — items to address before "Ready for review"

Warnings — informational, address before merging:

  • Pre-merge author checklist has unchecked items (e.g. "I've tested on Android"). Every box must be consciously checked — see docs/readme/ready-for-review.md.

See docs/readme/ready-for-review.md for the full Definition of Ready for Review.

@socket-security

socket-security Bot commented Jul 16, 2026

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Updatednpm/​@​metamask/​wallet@​7.0.1 ⏵ 8.0.075 +110076 +197 +1100
Updatednpm/​@​metamask/​seedless-onboarding-controller@​10.0.3 ⏵ 10.1.099 +110078 +198100

View full report

@github-actions

github-actions Bot commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

🧪 Flaky unit test detection

Run history flaky detection

View recent run history

Historical failure rate is a hint, not proof — review each suggestion in context. See the flaky-test-detection skill for the full pattern reference and manual audit workflow.

Failures / runs sampled per window:

File 7d 15d 30d
app/core/Engine/wallet-init/instance-options/seedless-onboarding-controller.test.ts 0/123 0/160 0/371

AI-detected flaky patterns

app/core/Engine/wallet-init/instance-options/seedless-onboarding-controller.test.ts

  • J3 — Missing jest.clearAllMocks() / jest.resetAllMocks() (high)
    • Both describe blocks have a beforeEach that re-sets mock implementations via .mockResolvedValue(...), but neither calls jest.clearAllMocks() first. This means call counts and call argument histories from previous tests accumulate across all tests in the suite. Every test that asserts toHaveBeenCalledWith(...) (e.g. the encryptWithKey, decryptWithKey, decrypt, and decryptWithDetail tests) is implicitly relying on the mock having been called exactly once — but if test execution order changes (e.g. via --randomize) or a prior test in the same describe block also invoked the same mock, the call history will contain extra entries. This can cause toHaveBeenCalledWith to match a stale call from a prior test, masking a real failure, or cause toHaveBeenCalledTimes assertions (if added) to fail. Adding jest.clearAllMocks() at the top of each beforeEach eliminates this risk by resetting call counts and argument histories before every test while still allowing the mockResolvedValue calls below it to set fresh implementations.
    • Suggested fix in app/core/Engine/wallet-init/instance-options/seedless-onboarding-controller.test.ts:83:
      -  beforeEach(() => {
      -    const {
      -      mockEncryptWithKey,
      -      mockDecryptWithKey,
      -      mockDecrypt,
      -      mockDecryptWithDetail,
      -    } = getEncryptorMocks();
      -    mockEncryptWithKey.mockResolvedValue(mockEncryptResult);
      -    mockDecryptWithKey.mockResolvedValue({ test: 'decrypted-data' });
      -    mockDecrypt.mockResolvedValue({ test: 'decrypted-data' });
      -    mockDecryptWithDetail.mockResolvedValue({
      -      vault: { test: 'decrypted-data' },
      -      exportedKeyString: 'key',
      -    });
      -  });
      +  beforeEach(() => {
      +    jest.clearAllMocks();
      +    const {
      +      mockEncryptWithKey,
      +      mockDecryptWithKey,
      +      mockDecrypt,
      +      mockDecryptWithDetail,
      +    } = getEncryptorMocks();
      +    mockEncryptWithKey.mockResolvedValue(mockEncryptResult);
      +    mockDecryptWithKey.mockResolvedValue({ test: 'decrypted-data' });
      +    mockDecrypt.mockResolvedValue({ test: 'decrypted-data' });
      +    mockDecryptWithDetail.mockResolvedValue({
      +      vault: { test: 'decrypted-data' },
      +      exportedKeyString: 'key',
      +    });
      +  });

This check is informational only and does not block merging.

@sonarqubecloud

Copy link
Copy Markdown

grvgoel81 and others added 2 commits July 23, 2026 11:39
…r init

Replace preview packages with the released @metamask/wallet@8.0.0 and
@metamask/seedless-onboarding-controller@10.1.0 so the mobile wallet-init
PR can finalize against stable published packages.

Co-authored-by: Cursor <cursoragent@cursor.com>
@github-actions

Copy link
Copy Markdown
Contributor

🔍 Smart E2E Test Selection

  • Selected E2E tags: SmokeAccounts, SmokeConfirmations, SmokeNetworkAbstractions, SmokeNetworkExpansion, SmokeSwap, SmokeStake, SmokeWalletPlatform, SmokeMoney, SmokePerps, SmokeMultiChainAPI, SmokePredictions, SmokeSeedlessOnboarding, SmokeSeedlessOnboardingExtended, SmokeBrowser, SmokeSnaps, SmokeMMConnect
  • Selected Performance tags: @PerformanceOnboarding, @PerformanceLogin
  • Risk Level: high
  • AI Confidence: 100%
click to see 🤖 AI reasoning details

E2E Test Selection:
Hard rule (controller-version-update): @MetaMask controller package version updated in package.json: @metamask/seedless-onboarding-controller. Running all tests.

Performance Test Selection:
The @metamask/wallet major version bump (^7 → ^8) changes how the SeedlessOnboardingController is initialized within the Wallet. This could affect onboarding flow performance (controller initialization timing, state restoration) and login/unlock performance (the controller's submitPassword and setLocked methods are part of the unlock flow). The @PerformanceOnboarding tag covers wallet creation and SRP import flows which go through the Engine initialization path that was refactored. The @PerformanceLogin tag covers session restoration and time-to-wallet-ready which depends on the controller initialization order. These are worth validating given the structural change to how the SeedlessOnboardingController is constructed and accessed.

View GitHub Actions results

@github-actions

Copy link
Copy Markdown
Contributor

E2E Fixture Validation — Failed
The fixture validation job failed. Review the logs

@github-actions

Copy link
Copy Markdown
Contributor

⚡ Performance Test Results

ℹ️ Performance test results are currently non-blocking and will not block this PR.

12 tests failed · 12 tests · 1 device

📱 Devices tested (1)

Android: Google Pixel 8 Pro (v14.0)

❌ Failed Tests (12)

🔬 To compare BrowserStack app profiling vs the last green run on main, copy/paste the App profiling check command for a failed test as a PR comment.

@assets-dev-team

Test Platform Device Reason Recording App profiling check
Asset View, SRP 1 + SRP 2 + SRP 3 Android Google Pixel 8 Pro (v14.0) Test error 📹 Watch @metamaskbot app-profiling-check --test "Asset View, SRP 1 + SRP 2 + SRP 3" --platform Android --device "Google Pixel 8 Pro+14.0" --run 30342196747

@metamask-mobile-platform

Test Platform Device Reason Recording App profiling check
Measure Warm Start: Login To Wallet Screen Android Google Pixel 8 Pro (v14.0) Test error 📹 Watch @metamaskbot app-profiling-check --test "Measure Warm Start: Login To Wallet Screen" --platform Android --device "Google Pixel 8 Pro+14.0" --run 30342196747
Cold Start: Measure ColdStart To Login Screen Android Google Pixel 8 Pro (v14.0) Test error 📹 Watch @metamaskbot app-profiling-check --test "Cold Start: Measure ColdStart To Login Screen" --platform Android --device "Google Pixel 8 Pro+14.0" --run 30342196747
Measure Warm Start: Warm Start to Login Screen Android Google Pixel 8 Pro (v14.0) Test error 📹 Watch @metamaskbot app-profiling-check --test "Measure Warm Start: Warm Start to Login Screen" --platform Android --device "Google Pixel 8 Pro+14.0" --run 30342196747
Cold Start after importing a wallet Android Google Pixel 8 Pro (v14.0) Test error 📹 Watch @metamaskbot app-profiling-check --test "Cold Start after importing a wallet" --platform Android --device "Google Pixel 8 Pro+14.0" --run 30342196747
Measure Cold Start To Onboarding Screen Android Google Pixel 8 Pro (v14.0) Test error 📹 Watch @metamaskbot app-profiling-check --test "Measure Cold Start To Onboarding Screen" --platform Android --device "Google Pixel 8 Pro+14.0" --run 30342196747

@metamask-onboarding-team

Test Platform Device Reason Recording App profiling check
Fresh SRP wallet creation performance Android Google Pixel 8 Pro (v14.0) Test error 📹 Watch @metamaskbot app-profiling-check --test "Fresh SRP wallet creation performance" --platform Android --device "Google Pixel 8 Pro+14.0" --run 30342196747
Onboarding Import SRP with +50 accounts, SRP 3 Android Google Pixel 8 Pro (v14.0) Test error 📹 Watch @metamaskbot app-profiling-check --test "Onboarding Import SRP with +50 accounts, SRP 3" --platform Android --device "Google Pixel 8 Pro+14.0" --run 30342196747
Account creation after fresh install Android Google Pixel 8 Pro (v14.0) Test error 📹 Watch @metamaskbot app-profiling-check --test "Account creation after fresh install" --platform Android --device "Google Pixel 8 Pro+14.0" --run 30342196747
Seedless Onboarding: Apple Login New User Android Google Pixel 8 Pro (v14.0) Test error 📹 Watch @metamaskbot app-profiling-check --test "Seedless Onboarding: Apple Login New User" --platform Android --device "Google Pixel 8 Pro+14.0" --run 30342196747
Seedless Onboarding: Telegram Login New User Android Google Pixel 8 Pro (v14.0) Test error 📹 Watch @metamaskbot app-profiling-check --test "Seedless Onboarding: Telegram Login New User" --platform Android --device "Google Pixel 8 Pro+14.0" --run 30342196747
Seedless Onboarding: Google Login New User Android Google Pixel 8 Pro (v14.0) Test error 📹 Watch @metamaskbot app-profiling-check --test "Seedless Onboarding: Google Login New User" --platform Android --device "Google Pixel 8 Pro+14.0" --run 30342196747
Compare all failed scenarios

@metamaskbot app-profiling-check --all --run 30342196747


Branch: feat/TO-921-wallet-init-seedless · Build: Normal · Commit: d43841a · View full run

@grvgoel81

Copy link
Copy Markdown
Contributor Author

Closing as as changes merged in PR: #33430

@grvgoel81 grvgoel81 closed this Jul 29, 2026
@github-actions github-actions Bot locked and limited conversation to collaborators Jul 29, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant